import type { ElementSelectors } from '../../lib/abstract'
import type { ComponentStyleIdType } from '../../types/interfaces'
import type { CheckboxOption, CheckboxProps } from './types'
import { UIComponent } from '../../lib/abstract'
import { ComponentStyleId, FLEX_JUSTIFY_MAP } from '../../types/constants'
import { styles } from './styles'
import { DEFAULT_CHECKBOX_PROPS } from './types'

export class Checkbox<T extends string = string> extends UIComponent<CheckboxProps<T>> {
  id: string = 'checkbox'
  readonly description: string = '复选框'
  readonly styleId: string = ComponentStyleId[this.name]
  private persistedOptions: Set<string> = new Set()

  get name(): ComponentStyleIdType {
    return 'Checkbox'
  }

  get className(): string {
    return 'custom-checkbox'
  }

  /**
   * 合并存储键
   */
  get mergedStorageKey(): string {
    return `${this.props.storagePrefix}${this.props.storageSeparator}${this.props.storageKey || this.props.id}`
  }

  constructor(props: CheckboxProps<T>) {
    super({
      ...DEFAULT_CHECKBOX_PROPS,
      ...props,
    } as CheckboxProps<T>)

    this.initOptionStates()
    this.initPersistedOptions()
    this.loadPersistedValues()

    // 注册样式
    this.registerStyles()
  }

  ELEMENT_SELECTORS: ElementSelectors = {

  }

  render(): string {
    const {
      id,
      label,
      labelTextPosition,
      options,
      position,
      selectedValues = [],
      showSelectAll,
      title,
    } = this.props

    return `
      <div class="${this.className}" data-id="${id}">
        ${label
          ? `
          <label class="checkbox-label" 
            style="text-align: ${labelTextPosition}"
            ${title ? `title="${title}"` : ''}>
            ${label}
          </label>
        `
          : ''}
        
        <div class="checkbox-options" style="${position ? `justify-content: ${FLEX_JUSTIFY_MAP[position]}` : ''}">
          ${showSelectAll
            ? `
              <label class="checkbox-item">
                <input type="checkbox" class="select-all-toggle">
                <span class="checkbox-label-text">全选</span>
              </label>
            `
            : ''}
          ${options.map(option => `
            <label class="checkbox-item ${option.disabled ? 'disabled' : ''}">
              
              <input 
                type="checkbox" 
                value="${option.value}"
                ${selectedValues.includes(option.value) ? 'checked' : ''}
                ${option.disabled ? 'disabled' : ''}
              >
              <span class="checkbox-label-text">${option.label}</span>
            </label>
          `).join('')}
        </div>
      </div>
    `
  }

  bindEvents(): void {
    const $container = this.$element

    // 单个选项变更
    $container?.find('input[type="checkbox"]:not(.select-all-toggle)').on('change', (e) => {
      const $checkbox = $(e.target)
      const value = $checkbox.val() as T
      const isChecked = $checkbox.is(':checked')

      this.saveOptionState(value, isChecked)
      this.updateSelectAllState()
      this.props.onChange?.(value, isChecked)
    })

    // 全选功能
    $container?.find('.select-all-toggle').on('change', (e) => {
      const isChecked = $(e.target).is(':checked')
      $container?.find('input[type="checkbox"]:not(.select-all-toggle)')
        .prop('checked', isChecked)
        .trigger('change')
    })
  }

  private updateSelectAllState(): void {
    const $container = this.$element
    const $checkboxes = $container?.find('input[type="checkbox"]:not(.select-all-toggle)')
    const $selectAll = $container?.find('.select-all-toggle')

    if ($checkboxes && $selectAll) {
      const checkedCount = $checkboxes.filter(':checked').length
      $selectAll
        .prop('checked', checkedCount === $checkboxes.length)
        .prop('indeterminate', checkedCount > 0 && checkedCount < $checkboxes.length)
    }
  }

  getStyles(): string {
    return styles(this.className)
  }

  /**
   * 设置选中值
   */
  setValues(values: string[]): void {
    this.$element?.find('input[type="checkbox"]').each((_, el) => {
      const $checkbox = $(el)
      $checkbox.prop('checked', values.includes($checkbox.val() as string))
    })
    this.updateSelectAllState()
  }

  /**
   * 获取当前选中值
   */
  getValues(): string[] {
    return this.$element?.find('input[type="checkbox"]:checked:not(.select-all-toggle)')
      .map((_, el) => $(el).val() as string)
      .get() || []
  }

  /**
   * 初始化需要持久化的选项
   */
  private initPersistedOptions(): void {
    this.props.options.forEach((option: CheckboxOption<T>) => {
      if (option.persist || this.props.autoPersist) {
        this.persistedOptions.add(this.getStorageKey(option))
      }
    })
  }

  /**
   * 获取存储键名
   */
  private getStorageKey(option: CheckboxOption<T>): string {
    return [
      this.props.storagePrefix,
      option.storageKey || option.value,
    ].filter(Boolean).join(this.props.storageSeparator)
  }

  /**
   * 加载持久化的选项值
   */
  private loadPersistedValues(): void {
    if (!this.persistedOptions.size)
      return

    const persistedValues = this.props.options
      .filter((opt: CheckboxOption<T>) => this.persistedOptions.has(this.getStorageKey(opt)))
      .filter((opt: CheckboxOption<T>) => this.loadOptionState(opt))
      .map((opt: { value: any }) => opt.value)

    this.props.selectedValues = [
      ...new Set([...this.props.selectedValues || [], ...persistedValues]),
    ]
  }

  /**
   * 初始化选项状态
   */
  private initOptionStates(): void {
    this.props.options.forEach((option: CheckboxOption<T>) => {
      // 只有需要持久化的选项才触发onInit
      if (option.persist || this.props.autoPersist) {
        const isChecked = this.loadOptionState(option)
        option.onInit?.(isChecked, this)
      }
    })
  }

  /**
   * 加载单个选项状态
   */
  private loadOptionState(option: CheckboxOption<T>): boolean {
    return this.props.useMergedStorage !== false
      ? this.loadMergedPreference(option)
      : this.loadPreference(this.getStorageKey(option))
  }

  /**
   * 保存选项状态到 localStorage
   */
  private saveOptionState(value: T, checked: boolean): void {
    const option = this.props.options.find((opt: { value: T }) => opt.value === value)

    if (!option || !this.persistedOptions.has(this.getStorageKey(option)))
      return

    this.props.useMergedStorage !== false
      ? this.saveMergedPreference(option, checked)
      : this.savePreference(this.getStorageKey(option), checked)
  }

  /**
   * 加载单个选项状态
   */
  private loadPreference(key: string): boolean {
    return localStorage.getItem(key) === 'true'
  }

  /**
   * 保存单个选项状态
   */
  private savePreference(key: string, value: boolean): void {
    localStorage.setItem(key, String(value))
  }

  /**
   * 获取所有选项的合并状态
   */
  private loadMergedPreferences(): Record<string, boolean> {
    try {
      const data = localStorage.getItem(this.mergedStorageKey)
      return data ? JSON.parse(data) : {}
    }
    catch {
      return {}
    }
  }

  /**
   * 保存所有选项的合并状态
   */
  private saveMergedPreferences(state: Record<string, boolean>): void {
    localStorage.setItem(this.mergedStorageKey, JSON.stringify(state))
  }

  /**
   * 加载单个选项状态（合并模式）
   */
  private loadMergedPreference(option: CheckboxOption<T>): boolean {
    const state = this.loadMergedPreferences()
    const key = this.getOptionStorageKey(option)
    return !!state[key]
  }

  /**
   * 保存单个选项状态（合并模式）
   */
  private saveMergedPreference(option: CheckboxOption<T>, value: boolean): void {
    const state = this.loadMergedPreferences()
    state[this.getOptionStorageKey(option)] = value
    this.saveMergedPreferences(state)
  }

  /**
   * 获取选项存储键（不带前缀）
   */
  private getOptionStorageKey(option: CheckboxOption<T>): string {
    return option.storageKey || option.value
  }

  destroy(): void {
    super.destroy()
  }
}
